//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "HetAtmRecord.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define LENGTHTEXT 100
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
HetAtmRecord::HetAtmRecord (): number(0),
                               chainID('\0'),
                               x(0),
                               y(0),
                               z(0),
                               occupancy(0),
                               tempFactor(0),
                               serial(0),
                               altLoc(0),
                               iCode(0) {
  
  this->name     = new String ();
  this->element  = new String ();
  this->atomName = new String();
  this->charge   = new String();
  
  this->toString = new String();
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
HetAtmRecord::HetAtmRecord (const HetAtmRecord& hetAtmRecord) {
  
  this->name       = new String(hetAtmRecord.name);
  this->number     = hetAtmRecord.number;
  
  this->chainID    = hetAtmRecord.chainID;

  this->x          = hetAtmRecord.x;
  this->y          = hetAtmRecord.y;
  this->z          = hetAtmRecord.z;

  this->occupancy  = hetAtmRecord.occupancy;
  this->tempFactor = hetAtmRecord.tempFactor;

  this->element    = new String(hetAtmRecord.element);
  
  this->serial     = hetAtmRecord.serial;
  this->altLoc     = hetAtmRecord.altLoc;
  this->iCode      = hetAtmRecord.iCode;
  this->atomName   = new String(hetAtmRecord.atomName);
  this->charge     = new String(hetAtmRecord.charge);
  
  this->toString   = new String ();
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
HetAtmRecord::HetAtmRecord (const HetAtmRecord* hetAtmRecord) {
  
  this->name       = new String(hetAtmRecord->name);
  this->number     = hetAtmRecord->number;

  this->chainID    = hetAtmRecord->chainID;

  this->x          = hetAtmRecord->x;
  this->y          = hetAtmRecord->y;
  this->z          = hetAtmRecord->z;

  this->occupancy  = hetAtmRecord->occupancy;
  this->tempFactor = hetAtmRecord->tempFactor;

  this->element    = new String(hetAtmRecord->element);
  
  this->serial     = hetAtmRecord->serial;
  this->altLoc     = hetAtmRecord->altLoc;
  this->iCode      = hetAtmRecord->iCode;
  this->atomName   = new String(hetAtmRecord->atomName);
  this->charge     = new String(hetAtmRecord->charge);
  
  this->toString   = new String ();
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
HetAtmRecord::~HetAtmRecord () {
  
  if (this->name)     delete this->name;
  if (this->element)  delete this->element;
  if (this->atomName) delete this->atomName;
  if (this->charge)   delete this->charge;
  
  if (this->toString) delete this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Name (String* name) {
  
  if (name) this->name->In(name);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Number (int number) {
  
  this->number = number;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::ChainID (char chainID) {
  
  this->chainID = chainID;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::X (double x) {
  
  this->x = x;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Y (double y) {
  
  this->y = y;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Z (double z) {
  
  this->z = z;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Occupancy (double occupancy) {
  
  this->occupancy = occupancy;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::TempFactor (double tempFactor) {
  
  this->tempFactor = tempFactor;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Element (String* element) {
  
  if (element) this->element->In(element);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Serial (int serial) {
  
  this->serial = serial;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::AltLoc (char altLoc) {
  
  this->altLoc = altLoc;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::ICode (char iCode) {
  
  this->iCode = iCode;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::AtomName (String* atomName) {
  
  if (atomName) this->atomName->In(atomName);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::Charge (String* charge) {
  
  if (charge) this->charge->In(charge);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* HetAtmRecord::Name (void) {
  
  return this->name;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int HetAtmRecord::Number (void) {
  
  return this->number;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char HetAtmRecord::ChainID (void) {
  
  return this->chainID;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double HetAtmRecord::X (void) {
  
  return this->x;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double HetAtmRecord::Y (void) {
  
  return this->y;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double HetAtmRecord::Z (void) {
  
  return this->z;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double HetAtmRecord::Occupancy (void) {
  
  return this->occupancy;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double HetAtmRecord::TempFactor (void) {
  
  return this->tempFactor;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* HetAtmRecord::Element (void) {
  
  return this->element;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int HetAtmRecord::Serial (void) {
  
  return this->serial;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char HetAtmRecord::AltLoc (void) {
  
  return this->altLoc;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char HetAtmRecord::ICode (void) {
  
  return this->iCode;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* HetAtmRecord::Charge (void) {
  
  return this->charge;
  
} 
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* HetAtmRecord::AtomName (void) {
  
  return this->atomName;
  
} 
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool HetAtmRecord::ReadFromString (String* data) {
  
  if (!data || !data->Length()) return false;
  
  String* tmp = NULL;
  
  tmp = data->SubStr(17, 20);
  if (tmp) { this->name->In(tmp);                 delete tmp; }
  else return false;
  
  tmp = data->SubStr(22, 26);
  if (tmp) { this->number = atoi(tmp->Out());     delete tmp; }
  else return false;
  
  tmp = data->SubStr(21, 22);
  if (tmp) { this->chainID = tmp->Out()[0];       delete tmp; }
  else return false;
  
  tmp = data->SubStr(30, 38);
  if (tmp) { this->x = atof(tmp->Out());          delete tmp; }
  else return false;
  
  tmp = data->SubStr(38, 46);
  if (tmp) { this->y = atof(tmp->Out());          delete tmp; }
  else return false;
  
  tmp = data->SubStr(46, 54);
  if (tmp) { this->z = atof(tmp->Out());          delete tmp; }
  else return false;
  
  tmp = data->SubStr(54, 60);
  if (tmp) { this->occupancy = atof(tmp->Out());  delete tmp; }
  else return false;
  
  tmp = data->SubStr(60, 66);
  if (tmp) { this->tempFactor = atof(tmp->Out()); delete tmp; }
  else return false;
  
  tmp = data->SubStr(76, 78);
  if (tmp) { this->element->In(tmp);              delete tmp; }
  else return false;
  
  tmp = data->SubStr(6, 11);
  if (tmp) { this->serial = atoi(tmp->Out());     delete tmp; }
  else return false;
  
  tmp = data->SubStr(16, 17);
  if (tmp) { this->altLoc = tmp->Out()[0];        delete tmp; }
  else return false;
  
  tmp = data->SubStr(26, 27);
  if (tmp) { this->iCode = tmp->Out()[0];         delete tmp; }
  else return false;
  
  tmp = data->SubStr(12, 16);
  if (tmp) { this->atomName->In(tmp);             delete tmp; }
  else return false;
  
  tmp = data->SubStr(78, 80);
  if (tmp) { this->charge->In(tmp);               delete tmp; }
  else return false;
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool HetAtmRecord::ReadFromString (char* data) {
  
  if (!data || !strlen(data)) return false;
  
  String dataChar;
  dataChar.In(data);
  
  return this->ReadFromString(&dataChar);    

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void HetAtmRecord::CleanData (void) {
  
  this->name->In("");
  
  this->number     = 0;

  this->chainID    = '\0';

  this->x          = 0;
  this->y          = 0;
  this->z          = 0;

  this->occupancy  = 0;
  this->tempFactor = 0;

  this->element->In("");
  
  this->serial     = 0;
  this->altLoc     = '\0';
  this->iCode      = '\0';
  
  this->atomName->In("");
  this->charge->In("");
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* HetAtmRecord::ToString (void) {
  
  char    buffer [LENGTHTEXT + 1];

  sprintf(buffer, "HETATM%5d %4s%c%3s %c%4d%c   %8.3f%8.3f%8.3f%6.2f%6.2f          %2s%2s\0", this->serial, 
                                                                                              this->atomName->Out(), 
                                                                                              this->altLoc,
                                                                                              this->name->Out(),
                                                                                              this->chainID,
                                                                                              this->number,
                                                                                              this->iCode,
                                                                                              this->x,
                                                                                              this->y,
                                                                                              this->z,
                                                                                              this->occupancy,
                                                                                              this->tempFactor,
                                                                                              this->element->Out(),
                                                                                              this->charge->Out());
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
HetAtmRecord HetAtmRecord::operator=(const HetAtmRecord& hetAtmRecord) {
  
  this->name->In(hetAtmRecord.name);
  
  this->number     = hetAtmRecord.number;
  
  this->chainID    = hetAtmRecord.chainID;

  this->x          = hetAtmRecord.x;
  this->y          = hetAtmRecord.y;
  this->z          = hetAtmRecord.z;

  this->occupancy  = hetAtmRecord.occupancy;
  this->tempFactor = hetAtmRecord.tempFactor;

  this->element->In(hetAtmRecord.element);
  
  this->serial     = hetAtmRecord.serial;
  this->altLoc     = hetAtmRecord.altLoc;
  this->iCode      = hetAtmRecord.iCode;
  
  this->atomName->In(hetAtmRecord.atomName);
  this->charge->In(hetAtmRecord.charge);
  
  return *this;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
